home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / tcl / tclx7_31.z / tclx7_31 / tcldev / tclX7.3a-p1 / tclsrc / profrep.tcl < prev    next >
Encoding:
Text File  |  1993-11-19  |  5.2 KB  |  150 lines

  1. #
  2. # profrep  --
  3. #
  4. # Generate Tcl profiling reports.
  5. #------------------------------------------------------------------------------
  6. # Copyright 1992-1993 Karl Lehenbauer and Mark Diekhans.
  7. #
  8. # Permission to use, copy, modify, and distribute this software and its
  9. # documentation for any purpose and without fee is hereby granted, provided
  10. # that the above copyright notice appear in all copies.  Karl Lehenbauer and
  11. # Mark Diekhans make no representations about the suitability of this
  12. # software for any purpose.  It is provided "as is" without express or
  13. # implied warranty.
  14. #------------------------------------------------------------------------------
  15. # $Id: profrep.tcl,v 3.0 1993/11/19 07:00:31 markd Rel $
  16. #------------------------------------------------------------------------------
  17. #
  18.  
  19. #@package: TclX-profrep profrep
  20.  
  21. #
  22. # Summarize the data from the profile command to the specified significant
  23. # stack depth.  Returns the maximum number of characters in any of the
  24. # procedure names.  (useful in columnizing reports).
  25. #
  26. proc profrep:summarize {profDataVar stackDepth sumProfDataVar} {
  27.     upvar $profDataVar profData $sumProfDataVar sumProfData
  28.  
  29.     if {(![info exists profData]) || ([catch {array size profData}] != 0)} {
  30.         error "`profDataVar' must be the name of an array returned by the `profile off' command"
  31.     }
  32.     set maxNameLen 0
  33.     foreach procStack [array names profData] {
  34.         foreach procName $procStack {
  35.             set maxNameLen [max $maxNameLen [clength $procName]]
  36.         }
  37.         if {[llength $procStack] < $stackDepth} {
  38.             set sigProcStack $procStack
  39.         } else {
  40.             set sigProcStack [lrange $procStack 0 [expr {$stackDepth - 1}]]
  41.         }
  42.         if [info exists sumProfData($sigProcStack)] {
  43.             set cur $sumProfData($sigProcStack)
  44.             set add $profData($procStack)
  45.             set     new [expr [lindex $cur 0]+[lindex $add 0]]
  46.             lappend new [expr [lindex $cur 1]+[lindex $add 1]]
  47.             lappend new [expr [lindex $cur 2]+[lindex $add 2]]
  48.             set sumProfData($sigProcStack) $new
  49.         } else {
  50.             set sumProfData($sigProcStack) $profData($procStack)
  51.         }
  52.     }
  53.     return $maxNameLen
  54. }
  55.  
  56. #
  57. # Generate a list, sorted in descending order by the specified key, contain
  58. # the indices into the summarized data.
  59. #
  60. proc profrep:sort {sumProfDataVar sortKey} {
  61.     upvar $sumProfDataVar sumProfData
  62.  
  63.     case $sortKey {
  64.         {calls} {set keyIndex 0}
  65.         {real}  {set keyIndex 1}
  66.         {cpu}   {set keyIndex 2}
  67.         default {
  68.             error "Expected a sort type of: `calls', `cpu' or ` real'"}
  69.     }
  70.  
  71.     # Build a list to sort cosisting of a fix-length string containing the
  72.     # key value and proc stack. Then sort it.
  73.  
  74.     foreach procStack [array names sumProfData] {
  75.         set key [format "%016d" [lindex $sumProfData($procStack) $keyIndex]]
  76.         lappend keyProcList [list $key $procStack]
  77.     }
  78.     set keyProcList [lsort $keyProcList]
  79.  
  80.     # Convert the assending sorted list into a descending list of proc stacks.
  81.  
  82.     for {set idx [expr [llength $keyProcList]-1]} {$idx >= 0} {incr idx -1} {
  83.         lappend sortedProcList [lindex [lindex $keyProcList $idx] 1]
  84.     }
  85.     return $sortedProcList
  86. }
  87.  
  88. #
  89. # Print the sorted report
  90. #
  91.  
  92. proc profrep:print {sumProfDataVar sortedProcList maxNameLen outFile
  93.                     userTitle} {
  94.     upvar $sumProfDataVar sumProfData
  95.     
  96.     if {$outFile == ""} {
  97.         set outFH stdout
  98.     } else {
  99.         set outFH [open $outFile w]
  100.     }
  101.  
  102.     # Output a header.
  103.  
  104.     set stackTitle "Procedure Call Stack"
  105.     set maxNameLen [max [expr $maxNameLen+6] [expr [clength $stackTitle]+4]]
  106.     set hdr [format "%-${maxNameLen}s %10s %10s %10s" $stackTitle \
  107.                     "Calls" "Real Time" "CPU Time"]
  108.     if {$userTitle != ""} {
  109.         puts $outFH [replicate - [clength $hdr]]
  110.         puts $outFH $userTitle
  111.     }
  112.     puts $outFH [replicate - [clength $hdr]]
  113.     puts $outFH $hdr
  114.     puts $outFH [replicate - [clength $hdr]]
  115.  
  116.     # Output the data in sorted order.
  117.  
  118.     foreach procStack $sortedProcList {
  119.         set data $sumProfData($procStack)
  120.         puts $outFH [format "%-${maxNameLen}s %10d %10d %10d" \
  121.                             [lvarpop procStack] \
  122.                             [lindex $data 0] [lindex $data 1] [lindex $data 2]]
  123.         foreach procName $procStack {
  124.             if {$procName == "<global>"} break
  125.             puts $outFH "    $procName"
  126.         }
  127.     }
  128.     if {$outFile != ""} {
  129.         close $outFH
  130.     }
  131. }
  132.  
  133. #------------------------------------------------------------------------------
  134. # Generate a report from data collect from the profile command.
  135. #   o profDataVar (I) - The name of the array containing the data from profile.
  136. #   o sortKey (I) - Value to sort by. One of "calls", "cpu" or "real".
  137. #   o stackDepth (I) - The stack depth to consider significant.
  138. #   o outFile (I) - Name of file to write the report to.  If omitted, stdout
  139. #     is assumed.
  140. #   o userTitle (I) - Title line to add to output.
  141.  
  142. proc profrep {profDataVar sortKey stackDepth {outFile {}} {userTitle {}}} {
  143.     upvar $profDataVar profData
  144.  
  145.     set maxNameLen [profrep:summarize profData $stackDepth sumProfData]
  146.     set sortedProcList [profrep:sort sumProfData $sortKey]
  147.     profrep:print sumProfData $sortedProcList $maxNameLen $outFile $userTitle
  148.  
  149. }
  150.